package practica3;

import java.util.Random;

import weka.classifiers.Evaluation;
import weka.classifiers.rules.OneR;
import weka.core.Instances;

/**Clase que entrena el clasificador OneR segun 5-fold CV*/
public class ScanParamsOneR {
	
	private Evaluation bestEvaluator = null;
	
	public ScanParamsOneR(){}
		
	/**
	 * Metodo que entrena el OneR, lo evalua segun 5-fold CV, y en base a la f-measure promedio, 
	 * determina cual es el valor de B mas apropiado.
	 * @param data Instancias para entrenar el clasificador OneR.
	 * @return El valor de B mas apropiado para entrenar el modelo.
	 */
	public int classify(Instances data) throws Exception{ 	
		int bestB = -1;
		double fmeasure = -1, fmeasureMax =-1;
		Evaluation evaluator = null;
		
		for(int b = 1; b<data.numInstances(); b++){ 
			
			OneR estimador = new OneR();
			estimador.setMinBucketSize(b); 	
			
			evaluator = new Evaluation(data);
			evaluator.crossValidateModel(estimador, data, 5, new Random(45));

			fmeasure = evaluator.weightedFMeasure();
			if(fmeasure>fmeasureMax){
				bestB = b;
				fmeasureMax = fmeasure;
				this.bestEvaluator = evaluator;
			}
		}
				
		this.print(bestB);
				
		return bestB;			
	}
	
	/**
	 * Metodo que imprime los resultados del barrido de parametros realizado por el clasificador.
	 * @param bestB mejor B encontrada
	 */
	private void print(int bestB) throws Exception{
		System.out.println("\n---------------------------------");
		System.out.println("RESULTADOS PARA EL ALGORITMO OneR");
		System.out.println("---------------------------------\n");
		System.out.println("CALIDAD ESPERADA");
		System.out.println("----------------");
		System.out.println("Mejor valor de B (numero de instancias minimo) en cada particion = " + bestB+"\n");
		System.out.println(this.bestEvaluator.toClassDetailsString());
		System.out.println(this.bestEvaluator.toSummaryString());
		System.out.println(this.bestEvaluator.toMatrixString());

	}
	
	/**
	 * Metodo para acceder al mejor evaluador
	 * @return devuelve el mejor evaluador
	 */
	public Evaluation getEvaluador(){
		return this.bestEvaluator;
	}
}
